use std::{env, path::Path};

use hound::{SampleFormat, WavReader};
use log::{info, trace};
use std::error::Error;
use whisper_rs::{WhisperContext, WhisperContextParameters, FullParams, SamplingStrategy};
use crate::{app_config::AppConfig, subtitles::SubTitles};

///读取语音文件
fn parse_wav_file(path: &Path) -> Vec<i16> {
    let reader = WavReader::open(path).expect("failed to read file");

    if reader.spec().channels != 1 {
        panic!("expected mono audio file");
    }
    if reader.spec().sample_format != SampleFormat::Int {
        panic!("expected integer sample format");
    }
    if reader.spec().sample_rate != 16000 {
        panic!("expected 16KHz sample rate,current audio rate: {}",reader.spec().sample_rate);
    }
    if reader.spec().bits_per_sample != 16 {
        panic!("expected 16 bits per sample");
    }

    reader
        .into_samples::<i16>()
        .map(|x| x.expect("sample"))
        .collect::<Vec<_>>()
}


pub fn extract_srt(audio_file:&str)->Result<SubTitles,Box<dyn Error+'static>>{
    trace!("current dir:{:?}",env::current_dir());
    let model_path=AppConfig::get().whisper_model_path();
    let model_path=Path::new(&model_path);
    if !model_path.exists(){
        return Err(format!("Model file: {} does not exist",model_path.to_str().unwrap()).into());
    }

    let ctx = WhisperContext::new_with_params(
		model_path.to_string_lossy().as_ref(),
		WhisperContextParameters::default()
	).expect("failed to load model");

    let mut state = ctx.create_state().expect("failed to create key");
    let audio_data = parse_wav_file(Path::new(audio_file));
    let mut samples = vec![0.0f32; audio_data.len()];
    whisper_rs::convert_integer_to_float_audio(&audio_data, &mut samples)
    .expect("failed to convert samples");

    // create a params object
	let mut params = FullParams::new(SamplingStrategy::default());
    params.set_initial_prompt("experience");
    params.set_progress_callback_safe(|progress| info!("Progress callback: {}%", progress));

    state
        .full(params, &samples)
        .expect("failed to convert samples");

    let num_segments = state
        .full_n_segments()
        .expect("failed to get number of segments");
    let mut subtitles=SubTitles::default();
    for i in 0..num_segments {
        let segment = state
            .full_get_segment_text(i)
            .expect("failed to get segment");
     
        let start_timestamp = state
            .full_get_segment_t0(i)
            .expect("failed to get start timestamp");
        let end_timestamp = state
            .full_get_segment_t1(i)
            .expect("failed to get end timestamp");
        subtitles.add(i as u32, start_timestamp, end_timestamp, segment);
    }
    Ok(subtitles)
    
}